bitkeeper revision 1.320 (3f0c3487S9CwVDQRe6TtSjZepJCw3w)
authorsos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>
Wed, 9 Jul 2003 15:28:07 +0000 (15:28 +0000)
committersos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>
Wed, 9 Jul 2003 15:28:07 +0000 (15:28 +0000)
Half of a way of getting /proc/dom0/vhd to return something
sensible.

xen/drivers/block/xen_block.c
xen/drivers/block/xen_segment.c
xen/include/hypervisor-ifs/block.h
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c

index cef7c5e544090bb1972d4dffc68c27264861be51..d1b8d855fdec49a4b4430de2fc054cef2a33b5f3 100644 (file)
@@ -102,6 +102,7 @@ static int do_block_io_op_domain(struct task_struct *p, int max_to_do);
 static void dispatch_rw_block_io(struct task_struct *p, int index);
 static void dispatch_probe_blk(struct task_struct *p, int index);
 static void dispatch_probe_seg(struct task_struct *p, int index);
+static void dispatch_probe_seg_all(struct task_struct *p, int index);
 static void dispatch_debug_block_io(struct task_struct *p, int index);
 static void dispatch_create_segment(struct task_struct *p, int index);
 static void dispatch_delete_segment(struct task_struct *p, int index);
@@ -387,6 +388,10 @@ static int do_block_io_op_domain(struct task_struct *p, int max_to_do)
            dispatch_probe_seg(p, i);
            break;
 
+       case XEN_BLOCK_PROBE_SEG_ALL:
+           dispatch_probe_seg_all(p, i);
+           break;
+
        case XEN_BLOCK_DEBUG:
            dispatch_debug_block_io(p, i);
            break;
@@ -566,7 +571,10 @@ static void dispatch_probe_blk(struct task_struct *p, int index)
     make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_BLK, rc);
 }
 
-static void dispatch_probe_seg(struct task_struct *p, int index)
+static void dispatch_probe_seg_common(struct task_struct *p,
+                                     struct task_struct *target,
+                                     int type,
+                                     int index)
 {
     extern void xen_segment_probe(struct task_struct *, xen_disk_info_t *);
 
@@ -589,12 +597,22 @@ static void dispatch_probe_seg(struct task_struct *p, int index)
     spin_unlock_irqrestore(&p->page_lock, flags);
 
     xdi = phys_to_virt(buffer);
-    xen_segment_probe(p, xdi);
+    xen_segment_probe(target, xdi);
 
     unlock_buffer(p, buffer, sizeof(xen_disk_info_t), 1);
 
  out:
-    make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_SEG, rc);
+    make_response(p, blk_ring->ring[index].req.id, type, rc);
+}
+
+static void dispatch_probe_seg(struct task_struct *p, int index)
+{
+    dispatch_probe_seg_common(p, p, XEN_BLOCK_PROBE_SEG, index);
+}
+
+static void dispatch_probe_seg_all(struct task_struct *p, int index)
+{
+    dispatch_probe_seg_common(p, NULL, XEN_BLOCK_PROBE_SEG_ALL, index);
 }
 
 static void dispatch_rw_block_io(struct task_struct *p, int index)
index 2f110423f0145b06acbe54ed27465b8bbd86632c..c82ff39e05595d9e410c5ee69ec61b9031cf2bdf 100644 (file)
@@ -162,7 +162,7 @@ void xen_segment_probe(struct task_struct *p, xen_disk_info_t *raw_xdi)
     for ( loop = 0; loop < XEN_MAX_SEGMENTS; loop++ )
     {
         if ( (xsegments[loop].mode == XEN_SEGMENT_UNUSED) ||
-             (xsegments[loop].domain != p->domain) )
+             (p && xsegments[loop].domain != p->domain) )
             continue;
 
         device = MK_VIRTUAL_XENDEV(xsegments[loop].segment_number);
index f5cf635afcad5b96030e8690be36ce3527471b2f..f269e57bd15c674d8ccf7f8bbbc41543c511a9a9 100644 (file)
@@ -50,6 +50,8 @@
 #define XEN_BLOCK_PHYSDEV_GRANT 10 /* grant access to range of disk blocks */
 #define XEN_BLOCK_PHYSDEV_PROBE 11 /* probe for a domain's physdev
                                      accesses */
+#define XEN_BLOCK_PROBE_SEG_ALL 12 /* prove for every domain's segments,
+                                     not just ours. */
 
 /* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */
 #define BLK_RING_SIZE        64
index 7bcf3297b1f70a124ba2f45d6e386e17653e8971..dbaffb76d915e5c25ca2e3246a35fb2d44704b25 100644 (file)
@@ -311,6 +311,7 @@ static int hypervisor_request(unsigned long   id,
     case XEN_BLOCK_PHYSDEV_PROBE:
     case XEN_BLOCK_PROBE_BLK:
     case XEN_BLOCK_PROBE_SEG:
+    case XEN_BLOCK_PROBE_SEG_ALL:
         if ( RING_FULL ) return 1;
        phys_device = (kdev_t) 0;
        sector_number = 0;
@@ -479,6 +480,7 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs)
         case XEN_BLOCK_SEG_CREATE:
         case XEN_BLOCK_SEG_DELETE:
         case XEN_BLOCK_PROBE_SEG:
+       case XEN_BLOCK_PROBE_SEG_ALL:
         case XEN_BLOCK_PROBE_BLK:
        case XEN_BLOCK_PHYSDEV_GRANT:
        case XEN_BLOCK_PHYSDEV_PROBE:
index 805f7336ec1d454f9bd84cbfa44056967868c84b..df65e8b046e1c30fb41e2398c35c33012bd0b034 100644 (file)
@@ -7,17 +7,70 @@
 #include "xl_block.h"
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
+#include <linux/seq_file.h>
 
 static struct proc_dir_entry *vhd;
 
 extern unsigned short xldev_to_physdev(kdev_t xldev);
 
-static int proc_read_vhd(char *page, char **start, off_t off,
-                        int count, int *eof, void *data)
+static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
 {
+    xen_disk_info_t *data;
+
+    if ( pos != NULL )
+        ++(*pos); 
+
+    data = v;
+    return data->count-- ? NULL : v;
+}
+
+static void *proc_vhd_start(struct seq_file *s, loff_t *ppos)
+{
+    loff_t pos = *ppos;
+    xen_disk_info_t *data;
+
+    data = kmalloc(sizeof(*data), GFP_KERNEL);
+    xenolinux_control_msg(XEN_BLOCK_PROBE_SEG_ALL, (char *)data, sizeof(*data));
+    data->count -= pos;
+
+    if (data->count > 0)
+       return data;
+
+    kfree(data);
+    return NULL;
+}
+
+static int proc_vhd_show(struct seq_file *s, void *v)
+{ 
+    xen_disk_info_t *data = v;
+
+    seq_printf (s,
+               "%4x %4x %lx\n",
+               data->disks[data->count - 1].device,
+               data->disks[data->count - 1].type,
+               data->disks[data->count - 1].capacity);
+
     return 0;
 }
 
+static void proc_vhd_stop(struct seq_file *s, void *v)
+{
+  kfree(v);
+}
+
+static struct seq_operations proc_vhd_op = {
+    .start         = proc_vhd_start,
+    .next          = proc_vhd_next,
+    .show          = proc_vhd_show,
+    .stop          = proc_vhd_stop
+};
+
+static int proc_open_vhd(struct inode *inode, struct file *file)
+{
+    return seq_open(file, &proc_vhd_op);
+}
+
+
 #define isdelim(c) \
   (c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0)
 
@@ -72,7 +125,7 @@ unsigned long to_number(char *string)                                /* atoi */
 }
 
 static int proc_write_vhd(struct file *file, const char *buffer,
-                         unsigned long count, void *data)
+                         size_t count, loff_t *offp)
 {
     char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL);
     char *string;
@@ -226,6 +279,14 @@ static int proc_write_vhd(struct file *file, const char *buffer,
     return res;
 }
 
+static struct file_operations proc_vhd_operations = {
+    open:         proc_open_vhd,
+    read:         seq_read,
+    llseek:       seq_lseek,
+    release:      seq_release,
+    write:        proc_write_vhd
+};
+
 /******************************************************************/
 
 int __init xlseg_proc_init(void)
@@ -236,8 +297,7 @@ int __init xlseg_proc_init(void)
         panic ("xlseg_init: unable to create vhd proc entry\n");
     }
     vhd->data       = NULL;
-    vhd->read_proc  = proc_read_vhd;
-    vhd->write_proc = proc_write_vhd;
+    vhd->proc_fops  = &proc_vhd_operations;
     vhd->owner      = THIS_MODULE;
 
     printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor installed\n");